package featuresWindows;

import helpFeaturesWindows.HelpPocketWindow;
import j3d.J3D;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;

import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.sun.j3d.utils.geometry.Box;

import CAD.MainFrame;

import operationSolids.CSGSolid;
import operationSolids.CompoundSolid;

import features.Block;
import features.Feature;
import features.PlanarFloorPocket;

import visualCAD.PocketWindowView;
import visualCAD.holeWindowView;

public class CreatePocket  extends PocketWindowView implements ActionListener{

	private J3D j3d = null;
	private PocketDinamicTopPanel1 pocketTopPanel;
	private PocketDinamicBottomPanel1 pocketBottomPanel;
	private Block block = null;
	public double positionX = 0,
				  positionY = 0, 
				  positionZ = 0, 
				  radius = 0, 
				  length = 0, 
				  width = 0, 
				  depth = 0;
	
	public CreatePocket(J3D j3d, Block block)
	{
		super();
		setVisible(true);
		pack();
		this.j3d = j3d;
		this.block = block;
		this.init();
		
	}
	public void init()
	{
		pocketSplitPanel.setTopComponent(pocketTopPanel=new PocketDinamicTopPanel1(
				positionX,positionY,radius,width,length)); 
		pocketSplitPanel.setBottomComponent(pocketBottomPanel=new PocketDinamicBottomPanel1(positionX,positionZ,radius,depth,width,length));
		pocketSplitPanel.setDividerLocation(0.5);
		double y = pocketTopPanel.faceY; 
		double x = pocketTopPanel.faceX;
		double z = pocketTopPanel.faceZ;
		helpButton.addActionListener(this);
		this.submitButton.addActionListener(this);
		this.cancelButton.addActionListener(this);
		yPositionSpinner.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				redrawDynamicComponents();
			}
		});
		zPositionSpinner.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				redrawDynamicComponents();
			}
		});
		xPositionSpinner.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				redrawDynamicComponents();
			}
		});
		depthSpinner.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				redrawDynamicComponents();
			}
		});
		lenghtSpinner.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				redrawDynamicComponents();
			}
		});
		widthSpinner.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				redrawDynamicComponents();
			}
		});
		radiusSpinner.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				redrawDynamicComponents();
			}
		});
		
		
	}
	private void redrawDynamicComponents(){
		try{
			radius=(Double)radiusSpinner.getValue();
			positionX=(Double)xPositionSpinner.getValue();
			positionY=(Double)yPositionSpinner.getValue();
			positionZ=(Double)zPositionSpinner.getValue();
			width=(Double)widthSpinner.getValue();
			length=(Double)lenghtSpinner.getValue();
			depth=(Double)depthSpinner.getValue();
			}
			catch (Exception e1) {
				JOptionPane.showMessageDialog(null, "error in entering data");
				e1.printStackTrace();
			}
			pocketSplitPanel.setTopComponent(pocketTopPanel=new PocketDinamicTopPanel1(positionX,positionY,radius,width,length));
			pocketSplitPanel.setBottomComponent(pocketBottomPanel=new PocketDinamicBottomPanel1(positionX,positionZ,radius,depth,width,length));
			pocketSplitPanel.setDividerLocation(0.5);
	}
	public void actionPerformed(ActionEvent evt) {
		Object origin = evt.getSource();
		
		
		if (origin.equals(this.submitButton))
		{
			this.ok();
		}
		else if (origin.equals(this.cancelButton))
		{
			this.cancel();
		}else if (origin.equals(this.helpButton))
		{
			new HelpPocketWindow();
		}
	}
	private void cancel()
	{
		// TODO Auto-generated method stub
		this.dispose();
	}
	private void ok() 
	{
		// TODO Auto-generated method stub
		boolean ok = true;
		
		//----------- positionX validation -----------//
		
		if (ok)
		{
			try
			{
				positionX = (Double)this.xPositionSpinner.getValue();
			}
			catch (Exception e)
			{
				JOptionPane.showMessageDialog(null, "error in entering data");
				ok = false;
			}
		}
		//------------- positionY validation ------------//
		if (ok)
		{
			try
			{
				positionZ = (Double)this.zPositionSpinner.getValue();
			}
			catch (Exception e)
			{
				JOptionPane.showMessageDialog(null, "error in entering data");
				ok = false;
			}
		}
		//------------- positionZ validation -------------//
		if (ok)
		{
			try
			{
				positionY = (Double)this.yPositionSpinner.getValue();
			}
			catch (Exception e)
			{
				JOptionPane.showMessageDialog(null, "error in entering data");
				ok = false;
			}
		}
		//-------------- radius Validation ---------------//
		if (ok)
		{
			try
			{
				radius = (Double)this.radiusSpinner.getValue();
			}
			catch (Exception e)
			{
				JOptionPane.showMessageDialog(null, "error in entering data");
				ok = false;
			}
		}
		//-------------- depth Validation ---------------//
		if (ok)
		{
			try
			{
				depth = (Double)this.depthSpinner.getValue();
			}
			catch (Exception e)
			{
				JOptionPane.showMessageDialog(null, "error in entering data");
				ok = false;
			}
		}
		//-------------- length Validation ---------------//
		if (ok)
		{
			try
			{
				length = (Double)this.lenghtSpinner.getValue();
			}
			catch (Exception e)
			{
				JOptionPane.showMessageDialog(null, "error in entering data");
				ok = false;
			}
		}
		//-------------- width Validation ----------------//
		if (ok)
		{
			try
			{
				width = (Double)this.widthSpinner.getValue();
			}
			catch (Exception e)
			{
				JOptionPane.showMessageDialog(null, "error in entering data");
				ok = false;
			}
		}
		//this.setResizable(false);
		PlanarFloorPocket pocket = new PlanarFloorPocket(Feature.PLANARFLOORPOCKET, null, (float)length, (float)width, (float)depth, 
				(float)positionX, (float)positionY, (float)positionZ,(float)radius, this.nameTextField.getText(),MainFrame.Face);
		this.j3d.removeSolid();
		this.j3d.addSolid(MainFrame.block.block);
		this.dispose();
	}
		
}
class PocketDinamicTopPanel1 extends JComponent{
	Shape pocket;
	Shape box;
	Shape axisX, axisY;
	double faceX = 0;
	double faceY = 0;
	double faceZ = 0;
	double multiplier= 0;
	double positionX,positionY, radius = 0, width=0, lenght=0;
	
	public PocketDinamicTopPanel1(double positionX, double positionY, double radius, double width, double lenght) {
		super();
		findXandY();
		multiplier = calculateMultiplier();
		this.positionX = positionX;
		this.positionY = positionY;
		this.radius = radius;
		this.width= width;
		this.lenght=lenght;
		pocket=createPocket(multiplier*(positionX)+10,multiplier*(positionY)+20,multiplier*(radius),multiplier*width,multiplier*lenght);
		box=createRectangle();
		axisX = verticalLine();
		axisY = horizontalLine();
	}
	protected Shape createRectangle() {
		Shape rectangle = new Rectangle2D.Double(10,20,faceX*multiplier,faceY*multiplier);
		return rectangle;
	}
	protected Shape createPocket(double posX,double posY, double radius,double width, double lenght) {
		double posXL;
		double posYL;
		posXL = posX-lenght/2;
		posYL = posY-width/2;
		this.radius = radius;
		this.width= width;
		this.lenght=lenght;
		Area pocket = new Area(new Rectangle2D.Double(posXL+radius,posYL,lenght-2*radius,width));
		pocket.add(new Area(new Ellipse2D.Double(
				posXL+(lenght-2*radius),
				posYL+(width-2*radius),
				2*radius,
				2*radius)));
		pocket.add(new Area(new Ellipse2D.Double(
				posXL+(lenght-2*radius),
				posYL,
				2*radius,
				2*radius)));
		pocket.add(new Area(new Ellipse2D.Double(
				posXL,
				posYL+(width-2*radius),
				2*radius,
				2*radius)));
		pocket.add(new Area(new Ellipse2D.Double(
				posXL,
				posYL,
				2*radius,
				2*radius)));
		pocket.add(new Area(new Rectangle2D.Double(
				posXL,
				posYL+radius,
				radius,
				width-2*radius
		)));
		pocket.add(new Area(new Rectangle2D.Double(
				posXL+lenght-radius,
				posYL+radius,
				radius,
				width-2*radius
		)));
		
		return pocket;
	}
	protected Shape verticalLine() {
		
		Shape axisY = new Line2D.Double(10, 20, 10, 50);
		return axisY;
	}
	protected Shape horizontalLine(){
		Shape axisX = new Line2D.Double(10, 20, 50, 20);
		return axisX;
	}
	public void paint(Graphics g) {
		double translateX, translateY = 0;
		translateY = this.multiplier * faceY;
		//System.out.println("translateY = " + translateY);
		Graphics2D g2 = (Graphics2D) g;
		g2.scale(1, -1);
		g2.translate(0, -215);
		g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		
		g2.setPaint(new Color(211, 211, 211));
		g2.fill(box);
		g2.setPaint(new Color(135, 206, 250));
		g2.fill(pocket);
		g2.setPaint(Color.BLUE);
		g2.draw(pocket);
		g2.setPaint(Color.BLACK);
		g2.draw(box);
		g2.setPaint(Color.RED);
		g2.draw(axisX);
		g2.draw(axisY);
		g2.scale(1, -1);
		g2.drawString("X", 50 ,-10);
		int x = (int) (multiplier*(positionX));
		int y = (int) (multiplier*(positionY));
		g2.drawString("x", +x+8 ,-y-16);
		g2.drawString("Y", 0, -50);
	}

	private double calculateMultiplier() {
		double multiplier = 195/faceY;
		if(faceX*multiplier > 370){
			multiplier = 370/faceX;
		}
		if(faceZ*multiplier > 180){
			multiplier = 180/faceZ;
		}
		return multiplier;
	}
	private void findXandY() {
		switch(MainFrame.Face){
		case MainFrame.TOPFACE:
			faceX = MainFrame.block.width;
			faceY = MainFrame.block.length;
			faceZ = MainFrame.block.height;
			break;
		case MainFrame.LOWERFACE:
			faceX = MainFrame.block.width;
			faceY = MainFrame.block.length;
			faceZ = MainFrame.block.height;
			break;
		case MainFrame.FRONTFACE:
			faceX = MainFrame.block.width;
			faceY = MainFrame.block.height;
			faceZ = MainFrame.block.length;
			break;
		case MainFrame.BACKFACE:
			faceX = MainFrame.block.width;
			faceY = MainFrame.block.height;
			faceZ = MainFrame.block.length;
			break;
		case MainFrame.EASTFACE:
			faceX = MainFrame.block.length;
			faceY = MainFrame.block.height;
			faceZ = MainFrame.block.width;
			break;
		case MainFrame.WESTFACE:
			faceX = MainFrame.block.length;
			faceY = MainFrame.block.height;
			faceZ = MainFrame.block.width;
			break;
		}
	}
}
class PocketDinamicBottomPanel1 extends JComponent{
	
	Shape smallBox;
	Shape bigBox;
	Shape axisX, axisY, centerLine1,centerLine2;
	double faceX = 0;
	double faceY = 0;
	double faceZ = 0;
	double multiplier= 0;
	
	
	private void findXandY() {
		switch(MainFrame.Face){
		case MainFrame.TOPFACE:
			faceX = MainFrame.block.width;
			faceY = MainFrame.block.length;
			faceZ = MainFrame.block.height;
			break;
		case MainFrame.LOWERFACE:
			faceX = MainFrame.block.width;
			faceY = MainFrame.block.length;
			faceZ = MainFrame.block.height;
			break;
		case MainFrame.FRONTFACE:
			faceX = MainFrame.block.width;
			faceY = MainFrame.block.height;
			faceZ = MainFrame.block.length;
			break;
		case MainFrame.BACKFACE:
			faceX = MainFrame.block.width;
			faceY = MainFrame.block.height;
			faceZ = MainFrame.block.length;
			break;
		case MainFrame.EASTFACE:
			faceX = MainFrame.block.length;
			faceY = MainFrame.block.height;
			faceZ = MainFrame.block.width;
			break;
		case MainFrame.WESTFACE:
			faceX = MainFrame.block.length;
			faceY = MainFrame.block.height;
			faceZ = MainFrame.block.width;
			break;
		}
	}
	private double calculateMultiplier() {
		double multiplier = 195/faceY;
		if(faceX*multiplier > 310){
			multiplier = 310/faceX;
		}
		if(faceZ*multiplier > 180){
			multiplier = 180/faceZ;
		}
		return multiplier;
	}
	
	public PocketDinamicBottomPanel1(double positionX, double positionZ, double radius, double depth, double width, double lenght) {
		super();
		findXandY();
		multiplier = calculateMultiplier();
		smallBox=createBox(multiplier*(positionX-lenght/2),multiplier*(-positionZ),multiplier*(lenght),multiplier*(depth));
		bigBox=createRectangle();
		axisX = verticalLine();
		axisY = horizontalLine();
		centerLine1 = centerLine(10+multiplier*(radius+positionX-(lenght/2)), multiplier*(-positionZ), multiplier*(lenght), multiplier*(depth));
		centerLine2 = centerLine(10+multiplier*(-radius+positionX+(lenght/2)), multiplier*(-positionZ), multiplier*(lenght), multiplier*(depth));
	}
	protected Shape createBox(double posX,double posY, double d1, double d2) {
		Shape rectangle = new Rectangle2D.Double(10+posX, 20+posY, d1, d2);
		return rectangle;
	}
	protected Shape createRectangle() {
		Shape rectangle = new Rectangle2D.Double(10,20,faceX*multiplier,faceZ*multiplier);
		return rectangle;
	}
	protected Shape verticalLine() {
		
		Shape axisY = new Line2D.Double(10, 20, 10, 50);
		return axisY;
	}
	protected Shape horizontalLine(){
		Shape axisX = new Line2D.Double(10, 20, 50, 20);
		return axisX;
	}
	protected Shape centerLine(double posX, double posY, double d1, double depth){
		Shape axisX = new Line2D.Double(posX, 20+posY, posX, 20+posY+depth);
		return axisX;
	}
	
	
	public void paint(Graphics g) {
		//System.out.println("translateY = " + translateY);
		Graphics2D g2 = (Graphics2D) g;
		g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		float dash1[] = {2.5f, 2.5f};
		float dash2[] = {3f, 1.5f,1f,1.5f};
		
		g2.setPaint(new Color(211, 211, 211));
		g2.fill(bigBox);
		g2.setPaint(new Color(135, 206, 250));
		g2.fill(smallBox);
		g2.setPaint(Color.BLUE);
		g2.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_BUTT, 
				BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f));
		g2.draw(smallBox);
		g2.setPaint(Color.BLACK);
		g2.setStroke(new BasicStroke());
		g2.draw(bigBox);
		g2.setPaint(Color.RED);
		g2.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_BUTT, 
				BasicStroke.JOIN_MITER, 10.0f, dash2, 0.0f));
		g2.draw(centerLine1);
		g2.draw(centerLine2);
		g2.draw(axisX);
		g2.draw(axisY);
		g2.drawString("X", 50 ,20);
		g2.drawString("-Z", 0, 50);
	}
}

